import { getToken } from '../utils/auth'  // 同步版本

// const BASE_URL = '/proxy-api'
const BASE_URL = 'http://192.168.3.200:8082'


const TIMEOUT = 15000

// 构建 multipart/form-data 请求体
function buildMultipartBody(formData : any, boundary : any) {
	let body = '';
	for (const key in formData) {

		body += `--${boundary}\r\n`;
		body += `Content-Disposition: form-data; name="${key}"\r\n\r\n`;
		body += `${formData[key]}\r\n`;
	}

	body += `--${boundary}--\r\n`;
	return body;
}

// 工具函数：对象转URL编码字符串
const encodeFormData = (data : any) => {
	return Object.keys(data)
		.map(key =>
			encodeURIComponent(key) + '=' +
			encodeURIComponent(data[key])
		)
		.join('&');
};

// 请求实例
class Request {
	private config : UniApp.RequestOptions

	constructor() {
		this.config = {
			url: '',
			method: 'GET',
			timeout: TIMEOUT,
			header: { 'Content-Type': 'application/json;charset=UTF-8' }
		}
	}

	// 核心请求方法
	async request<T>(options : UniApp.RequestOptions) : Promise<T> {
		try {

			// 显式声明合并后的配置对象
			const mergedOptions : UniApp.RequestOptions = {
				...this.config,  // 默认配置
				...options,      // 传入配置
				header: {        // 合并header
					...this.config.header,
					...options.header
				}
			}


			const token = getToken()
			if (token) {
				mergedOptions.header!['Authorization'] = `Bearer ${token}`
			}
			mergedOptions.header!['X-Access-Token'] = token || 'X-Access-Token'

			const response = await uni.request(mergedOptions)
			// 还原

			this.config.header['Content-Type'] = `application/json`
			return this.handleResponse<T>(response)
		} catch (error) {
			// this.handleError(error)
			throw error
		}
	}

	private handleResponse<T>(response : UniApp.RequestSuccessCallbackResult) : T {

		console.log(response);
		if (response.statusCode !== 200) {
			throw new Error(`请求失败: ${response.statusCode}`)
		}
		const res = response.data as { code : number; data : T; msg : string }
		if (res.code !== 200) {
			uni.showToast({ title: res.msg, icon: 'none' })
			throw new Error(res.msg)
		}
		return res
	}

	private handleError(error : any) : void {
		uni.showToast({ title: '网络请求失败', icon: 'none' })
		console.error('请求错误:', error)
	}

	// 快捷方法
	get<T>(url : string, params ?: object) {
		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'GET', data: params })
	}

	post<T>(url : string, data ?: object) {
		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'POST', data: data || {} })
	}
	putFormDataUploadFile<T>(url : string, data ?: any) {
		// 上传文件
		uni.uploadFile({
			url: `${BASE_URL}${url}`,
			filePath: '',
			name: '',
			formData: data,
			success: (response : any) => {
				uni.showToast({ title: response.msg, icon: 'success' })
				uni.navigateBack()
				console.log('上传成功', JSON.stringify(data), JSON.stringify(response.data));
			},
			fail: (error) => {
				console.error('上传失败', error);
			}
		});
	}

	// 显示 192.168.3.200:8082/opt/uploads/
	uploadFile<T>(url : string, filePath : string, formData ?: any,) {
		// 上传文件
		return new Promise(async (resolve, reject) => {
			uni.uploadFile({
				url: `${BASE_URL}${url}`,
				filePath: filePath,
				name: 'file',
				formData: formData,
				success: (response : any) => {
					uni.showToast({ title: '上传成功', icon: 'success' })

					console.log('上传成功', response);
					console.log(JSON.parse(response.data));
					resolve(JSON.parse(response.data).msg)
				},
				fail: (error) => {
					console.error('上传失败', error);
				}
			});

		})
	}


	postFormDataUploadFile<T>(url : string, data ?: any) {

		const formData = {};
		for (var key in data) {
			if (data.hasOwnProperty(key)) {
				if (key !== 'files' && key !== 'file') {
					formData[key] = data[key]
				}

			}
		}

		data.files.forEach((file, index) => {
			formData[`files[${index}]`] = file;
		});

		console.log(data);


		// 上传文件
		uni.uploadFile({
			url: `${BASE_URL}${url}`,
			files: data.files, // 多文件数组
			formData: formData,
			name: 'files',
			success: (response : any) => {
				uni.showToast({ title: response.msg, icon: 'success' })
				uni.navigateBack()
				console.log('上传成功', JSON.stringify(data), JSON.stringify(response.data));
			},
			fail: (error) => {
				console.error('上传失败', error);
			}
		});



	}
	postFormDataFiles<T>(url : string, data ?: any) {
		// const encodedData = encodeFormData(data);
		const formData = new FormData();
		for (const key in data) {
			if (['imageFiles', 'files'].includes(key)) {
				data[key].forEach((file : any) => {
					formData.append(key, file, file.name);
				});
			} else {
				formData.append(key, data[key]);
			}
		}

		// 发送请求（无需手动设置 Content-Type）
		try {
			return fetch(`${BASE_URL}${url}`, {
				method: "POST",
				body: formData
			}).then((response : any) => {

				// 检查 HTTP 状态码
				if (!response.ok) {
					throw new Error(`HTTP 错误! 状态码: ${response.status}`);
				}
				// 解析 JSON 类型的 body
				return response.json();

			}, (error : any) => {
				console.error('请求失败:', error);
			}).then(data => {
				console.log(data);
				if (data.code !== 200) {
					throw new Error(`请求失败: ${data.code}`)
				}

				if (data.code !== 200) {
					uni.showToast({ title: data.msg, icon: 'none' })
					throw new Error(data.msg)
				}
				return data
			}).catch(error => {
				// 处理错误
				console.error('请求失败:', error);
			});




		} catch (error) {
			throw error;
		}

	}
	postFormData<T>(url : string, data ?: any) {

		// 生成唯一边界字符串（重要！）
		const boundary = '----WebKitFormBoundary' + Date.now().toString(16);
		const body = buildMultipartBody(data, boundary);

		this.config.header['Content-Type'] = `multipart/form-data; boundary=${boundary}`


		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'POST', data: body || {} })
	}
	postWWWForm<T>(url : string, data ?: object) {
		this.config.header['Content-Type'] = `application/x-www-form-urlencoded`

		const encodedData = encodeFormData(data);

		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'POST', data: encodedData || {} })
	}
	delete<T>(url : string, data ?: object) {
		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'DELETE', data: data || {} })
	}
	put<T>(url : string, data ?: object) {
		return this.request<T>({ url: `${BASE_URL}${url}`, method: 'PUT', data: data || {} })
	}
}

export const http = new Request()